package com.epalmpay.controller.apiweixin;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;

import com.epalmpay.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.epalmpay.commom.BaseController;
import com.epalmpay.entity.Member;
import com.epalmpay.entity.MemberICCardInfo;
import com.epalmpay.enumdef.BizEnum;
import com.epalmpay.util.Response;
import com.epalmpay.exception.ApplicationException;
import com.epalmpay.service.member.IMemberService;
import com.epalmpay.service.sms.ISMSService;
import com.epalmpay.service.weixin.IWxApiIcCardService;
import com.epalmpay.util.Const;
import com.epalmpay.util.Tools;
import redis.clients.jedis.Jedis;


/**
 * 实体卡微信端接口
 * @author Administrator
 *
 */
@Controller
@RequestMapping(value="/api/icCard")
public class WxApiIcCardController extends BaseController{
	
	@Resource
	private IMemberService memberService;
	
	@Resource
	private IWxApiIcCardService wxApiIcCardService;
	
	@Autowired
	protected ISMSService smsService;
	
	/**
	 * 传入会员ID
	 * 根据会员ID获取会员预留手机号
	 * @param memberId
	 * @return
	 */
	@RequestMapping(value="/selectMemberPhoneByMemberId",method = {RequestMethod.GET,RequestMethod.POST})
	@ResponseBody
	public Response selectMemberPhoneByMemberId(String memberId){
		logBefore(logger, "根据memberId查询会员信息");
		
		HashMap<String, String> result=new HashMap<String,String>();
		result.put("会员ID", memberId);
		String nullParam = Response.checkNull(result);
		if(nullParam!=null){
			return Response.getError(nullParam + "不能为空");
		}
			try {
				Member me = new Member();
				me.setId(Long.parseLong(memberId));
				Member member=memberService.findMemberinfo(me);
				if(member!=null){
					Map<String,Object> resultMap=new HashMap<String,Object>();
					resultMap.put("user_id", member.getId());
					resultMap.put("user_tele", member.getPhone());
					resultMap.put("group_id", member.getGroupId());
					return Response.getSuccess(resultMap);
				}else{
					return Response.getError("未查询到记录");
				}
				
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				return Response.getError("服务器异常");
			}
		
	}
	
	
	
	/**
	 * 发送短信验证码
	 * @param phone
	 * @param type
	 * @param groupId
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "/sendPhoneCode", method = {RequestMethod.GET,RequestMethod.POST})
	@ResponseBody
	public Response sendCode(String phone,String type,Long groupId) throws Exception {
		logBefore(logger, "发送短信验证码");
		HashMap<String, String> resultMap = new HashMap<String, String>();
		resultMap.put("手机号码", phone);
		resultMap.put("短信类型", type);		
		String nullParam=Response.checkNull(resultMap);
		if (null != nullParam) {
			return Response.getError(nullParam+"不能为空");
		}
		Map<String,String> map = new HashMap<String,String>();
		Date date=new Date();
		//短信验证码2分钟发送一次 验证码有效时间30分钟
		RedisUtil redisUtil = new RedisUtil();
		Jedis jedis = redisUtil.getJedis();
		//Date verifyDate=(Date)Const.CacheMapObject.get(Const.SESSION_TiME_CODE+phone+type);
		Long verifyDate = jedis.ttl(Const.SESSION_PHONE_CODE+phone+type);
		if(verifyDate!=null){
			//当前时间120秒后
			/*Calendar calendar = Calendar.getInstance();
			calendar.setTime(verifyDate);    
			calendar.add(Calendar.SECOND, 120);  
			if(calendar.getTime().after(date)){
				return Response.getError("2分钟内只能发送1条校验码。");
			}*/
			if(verifyDate >= 1680){//如果剩余生成时间大于1680秒，则抛出异常
				return Response.getError("2分钟内只能发送1条校验码。");
			}
		}
		try {
			String code="true".equals("false") ? "000000" : String.format("%.0f",(Math.random()*9+1)*100000);
    		this.logger.info("---验证码---:"+code);
    		Map<String, String> params=new HashMap<String, String>(); 
    		boolean flag=smsService.sendRegionCode(groupId, code, BizEnum.SMSTemplateType.temp_SMS_104630027.getType(), phone, params);
    		if(flag){
    			//Const.CacheMapObject.put(Const.SESSION_PHONE_CODE+phone+type,code);
				//Const.CacheMapObject.put(Const.SESSION_TiME_CODE+phone+type, date);
				jedis.setex(Const.SESSION_PHONE_CODE+phone+type, 1800, code);
    		}
    		jedis.quit();
			return Response.getSuccess(map);
		} catch (Exception e) {
			e.printStackTrace();
			return Response.getError("验证码发送异常");
		}
	
	}
	
	/**
	 * 实体卡绑定
	 * 传入实体卡号，密码，验证码
	 * 验证实体卡是否存在，是否冲突，密码是否正确，验证码是否正确
	 * 如果都满足条件，则进行实体卡绑定
	 * @param memberId
	 * @param icCardNo
	 * @param icCardPwd
	 * @param phone
	 * @param code
	 * @param type
	 * @return 134749
	 */
	@RequestMapping(value="/toPinlessIcCard",method = {RequestMethod.GET,RequestMethod.POST})
	@ResponseBody
	public Response updatePinlessIcCard(String memberId,String icCardNo,String icCardPwd,String phone,String code,String type){
		logBefore(logger, "实体卡绑定");
		Map<String, Object> map = new HashMap<String, Object>();
		
		try {
			HashMap<String, String> resultMap = new HashMap<String, String>();
			resultMap.put("会员编号", memberId);
			resultMap.put("手机号码", phone);
			resultMap.put("短信验证码", code);
			resultMap.put("短信类型", type);
			String nullParam=Response.checkNull(resultMap);
			if (null != nullParam) {
				return Response.getError(nullParam+"不能为空");
			}
			
			//验证实体卡状态
			if(wxApiIcCardService.selectIcCardStatus(icCardNo)){
				//验证实体卡是否存在，密码是否正确
				if(wxApiIcCardService.selectAndCheckIcCardPwd(icCardNo, icCardPwd)){
					
					//校验验证码
					RedisUtil redisUtil = new RedisUtil();
					Jedis jedis = redisUtil.getJedis();
					String codemessage=jedis.get(Const.SESSION_PHONE_CODE+phone+type);//(String)Const.CacheMapObject.get(Const.SESSION_PHONE_CODE+phone+type);
					logBefore(logger, "原验证码"+codemessage);
					if(Tools.isEmpty(codemessage)||!codemessage.equals(code)){ 
						return Response.getError("验证码输入错误");
					}
					
					wxApiIcCardService.updatePinlessIcCard(icCardNo, memberId);//绑卡操作，修改实体卡相关状态，增加会员钱包余额
					
					//Const.CacheMapObject.remove(Const.SESSION_PHONE_CODE+phone+type);
					jedis.del(Const.SESSION_PHONE_CODE+phone+type);
				    map.put("message", "处理成功");
					jedis.quit();
					return Response.getSuccess(map);
				}else{
					logger.error("绑卡时校验实体卡不存在或密码不正确！");
					return Response.getError("该实体卡不存在或实体卡密码不正确！");
				}
			}else{
				logger.error("绑卡时校验实体卡状态，该实体卡已被激活或使用，不可被绑定！");
				return Response.getError("该实体卡已被激活或已被使用，不可被绑定！");
			}
		} catch (ApplicationException ae) {
			logger.error(ae);
			return Response.getError(ae.getErrMsg());
		} catch (Exception e){
			logger.error(e);
			return Response.getError("服务器异常");
		}
		
	}
	
	/**
	 * 根据传入的会员ID
	 * 查找该会员是否有绑定的，并且状态为已绑定的实体卡，用于准备挂失和改密用
	 * 如果没有，就返回null
	 * 如果有，则返回实体卡卡号和实体卡状态
	 * @param memberId
	 * @return
	 */
	@RequestMapping(value="/selectIcCardNoByMemberId",method = {RequestMethod.GET,RequestMethod.POST})
	@ResponseBody
	public Response selectIcCardNoByMemberId(String memberId){
		logBefore(logger, "根据会员ID查找实体卡");
		if(Tools.isEmpty(memberId)){
			return Response.getError("会员ID不可为空！");
		}else{
			try {
				MemberICCardInfo memberIcCardInfo =wxApiIcCardService.selectIcCardByMemberId(memberId);
				Map<String,Object> map =new HashMap<String,Object>();
				if(memberIcCardInfo!=null){
					map.put("icCardNo", memberIcCardInfo.getIccardNo());
					map.put("status", memberIcCardInfo.getStatus());
					map.put("switchStatus", memberIcCardInfo.getSwitchStatus());
					return Response.getSuccess(map);
				}
				return Response.getError("未找到实体卡或未绑定实体卡！");
			} catch (Exception e){
				e.printStackTrace();
				return Response.getError("服务器异常！");
			}
		}
		
	}
	
	/**
	 * 实体卡挂失
	 * 传入实体卡状态，实体卡卡号，实体卡启用禁用状态
	 * 如果实体卡状态为已绑定，则表示可以进行挂失操作
	 * 根据传入的status和switchStatus改变实体卡状态
	 * 点击确定挂失后48小时内状态为已挂失，禁用；48小时后状态为废弃，禁用；手动进行绑定新卡操作；
	 * 48小时内点击取消挂失后状态为未绑定，禁用；手动进行重新绑卡操作流程
	 * status:实体卡状态
	 * switchStatus：实体卡启用禁用状态
	 * targetStatus:要改变成的状态：1.未绑定(未激活),2.已绑定(已激活),3.已废弃,4.已挂失
	 * targetSwitchStatus:要改变成的状态：0.禁用，1.启用
	 * @param icCardNo
	 * @param switchStatus
	 * @param targetSwitchStatus
	 * @param status
	 * @param targetStatus
	 * @return
	 */
	@RequestMapping(value="/toLostIcCard",method = {RequestMethod.GET,RequestMethod.POST})
	@ResponseBody
	public Response updateIcCardStatusAndSwitchStatus(String icCardNo,String switchStatus,String targetSwitchStatus,String status,String targetStatus){
		logBefore(logger, "实体卡挂失");
		if(Tools.isEmpty(switchStatus)&&Tools.isEmpty(icCardNo)&&Tools.isEmpty(status)){
			return Response.getError("实体卡号,实体卡状态均不可为空！");
		}
		//实体卡状态不是已绑定状态时，不可挂失，不可改密
		if(status.equals("2")){
			try {
				wxApiIcCardService.updateIcCardStatus(icCardNo,targetSwitchStatus, targetStatus,"0");
				return Response.getSuccess("挂失成功！");
			} catch (ApplicationException ae) {
				// TODO Auto-generated catch block
				ae.printStackTrace();
				return Response.getError("挂失失败！");
			} catch (Exception e){
				e.printStackTrace();
				return Response.getError("系统异常！");
			}
		}
		return Response.getError("未绑定的实体卡不可挂失！");
		
	}
	
	/**
	 * 绑卡完成后进入实体卡管理时，先对实体卡进行是否挂失超时判断，并按条件进行自动废弃实体卡操作
	 * @param memberId
	 * @return
	 */
	@RequestMapping(value="/refreshIcCardStatus",method = {RequestMethod.GET,RequestMethod.POST})
	@ResponseBody
	public Response updateIcCardTimeOut(String memberId){
		logBefore(logger, "挂失超时后自动废弃！");
		try {
			MemberICCardInfo memberICCardInfo = new MemberICCardInfo();
			memberICCardInfo=wxApiIcCardService.selectIcCardTimeOut(Long.parseLong(memberId));
			if(memberICCardInfo!=null||memberICCardInfo.getStatus().equals("4")){
			     try {
			    	 SimpleDateFormat formatter=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
					 String now,target;
					 Date nowDateTime,targetModified; 
					 now=formatter.format(new Date());
					 target=formatter.format(memberICCardInfo.getGmtModified());
				     nowDateTime = formatter.parse(now);
				     targetModified=formatter.parse(target);
				     double L = nowDateTime.getTime() - targetModified.getTime();  
				     double d = L/(24*60*60*1000);
				     if(d>=2){
				    	//该会员绑定的实体卡已挂失超过48小时，需要自动废弃；
				    	 //
				    	wxApiIcCardService.updateIcCardStatus(memberICCardInfo.getIccardNo(),"0","3","2");
				    	logger.error("挂失已超过48小时，已自动废弃该实体卡！");
				    	return Response.getSuccess("挂失已超过48小时，已自动废弃该实体卡！");
				     }else{
				    	 logger.error("挂失未超过48小时，不可自动废弃该实体卡！");
				    	 return Response.getSuccess("挂失未超过48小时，不可自动废弃该实体卡！");
				     }
				     
				} catch (ParseException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					logger.error(e);
					return Response.getError("系统异常！");
				}  
			     
			}else{
				return Response.getError("该会员没有绑定实体卡或者实体卡未挂失！");
			}
		} catch (ApplicationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			logger.error(e);
			return Response.getError("系统异常！");
		}
		
	}
	
	/**
	 * 取消挂失，48小时内有效
	 * 传入实体卡卡号，状态，启用禁用状态
	 * 修改实体卡status状态为未绑定，禁用
	 * @param icCardNo
	 * @param targetStatus
	 * @param targetSwitchStatus
	 * @return
	 */
	@RequestMapping(value="/toCancelLostIcCard",method = {RequestMethod.GET,RequestMethod.POST})
	@ResponseBody
	public Response updateIcCardCancel(String icCardNo,String targetSwitchStatus,String targetStatus){
		try {
			 SimpleDateFormat formatter=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
			 String now,target;
			 Date nowDateTime,targetModified; 
			 now=formatter.format(new Date());
			 target=formatter.format(wxApiIcCardService.selectIcCardByIcCardNo(icCardNo).getGmtModified());
		     nowDateTime = formatter.parse(now);
		     targetModified=formatter.parse(target);  
		     double L = nowDateTime.getTime() - targetModified.getTime();  
		     double d = L/(24*60*60*1000);
		    if(d>=2){
		    	//挂失时间到当前时间已经超过48小时了，不可取消挂失了
		    	try {
					wxApiIcCardService.updateIcCardStatus(icCardNo,"0","3","2");
					logger.error("挂失已超过48小时，已自动废弃该实体卡！");
			    	return Response.getSuccess("挂失已超过48小时，不可取消挂失,已自动废弃该实体卡！");
				} catch (ApplicationException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					logger.error("取消挂失操作"+e);
					return Response.getError("系统异常！");
				}
		    }else{
		    	//挂失时间到当前时间未超过48小时，可以取消挂失
		    	try {
					wxApiIcCardService.updateIcCardStatus(icCardNo,targetSwitchStatus,targetStatus,"1");
					return Response.getSuccess("取消挂失成功，可重新绑卡！");
				} catch (ApplicationException e) {
					// TODO Auto-generated catch block
					logger.error("取消挂失操作"+e);
					return Response.getError("取消挂失失败！");
				}
		    }
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			logger.error("取消挂失操作"+e);
			return Response.getError("系统异常处理！");
		}
	    
	}
	
	/**
	 * 实体卡改密
	 * 传入实体卡状态status，实体卡卡号icCardNo，实体卡改密验证码code，实体卡新密码newIcCardPwd,会员电话phone，短信类型type
	 * 如果实体卡处于绑定状态，则表示可以进行改密
	 * 验证验证码是否正确，正确就根据实体卡号和新密码进行改密操作
	 * @param status
	 * @param icCardNo
	 * @param code
	 * @param newIcCardPwd
	 * @param phone
	 * @param type
	 * @return
	 */
	@RequestMapping(value="/updateIcCardPwd",method = {RequestMethod.GET,RequestMethod.POST})
	@ResponseBody
	public Response updateIcCardPwd(String status,String icCardNo,String code,String newIcCardPwd,String phone,String type){
		logBefore(logger, "密码修改");
		
		if(status.equals("2")){
			RedisUtil redisUtil = new RedisUtil();
			Jedis jedis = redisUtil.getJedis();
			String codemessage=jedis.get(Const.SESSION_PHONE_CODE+phone+type);//(String)Const.CacheMapObject.get(Const.SESSION_PHONE_CODE+phone+type);
			logBefore(logger, "原验证码"+codemessage);
			if(Tools.isEmpty(codemessage)||!codemessage.equals(code)){ 
				return Response.getError("验证码输入错误");
			}
			
			try {
				wxApiIcCardService.updateIcCardPwd(icCardNo, newIcCardPwd);
				jedis.del(Const.SESSION_PHONE_CODE+phone+type);
				jedis.quit();
				return Response.getSuccess("修改密码成功！");
			} catch (ApplicationException ae) {
				// TODO Auto-generated catch block
				ae.printStackTrace();
				return Response.getSuccess("实体卡密码修改失败！");
			} catch (Exception e){
				e.printStackTrace();
				return Response.getError("系统异常！");
			}
		}else{
			return Response.getError("实体卡不可修改密码！");
		}
		
	}
	
}
